package icu.zhhll.datasource.aspect;

import icu.zhhll.datasource.annotation.DataSource;
import icu.zhhll.datasource.common.DataSourceHolder;
import icu.zhhll.datasource.dynamic.DynamicDataSource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;

import java.lang.reflect.Method;

/**
 * <p>
 * <aop:aspectj-autoproxy/>
 * <bean id="dataSourceAspect" class="icu.zhhll.datasource.aspect.DataSourceAspect"/>
 * </p>
 * 数据源切换切面
 *
 * @author zh
 * @date 2023/10/8 15:06
 */
@Order(1) // 需要比事务切面早
@Aspect
public class DataSourceAspect {
    private final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class);

    @Pointcut(value = "@annotation(icu.zhhll.datasource.annotation.DataSource)")
    public void pointcut() {

    }

    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        String name = getDataSourceName(joinPoint);
        LOGGER.debug("{}线程拦截切换数据源{}", Thread.currentThread().getName(), name);
        DataSourceHolder.setCurDataSource(name);
    }

    @After(value = "pointcut()")
    public void after() {
        DataSourceHolder.clearDataSource();
    }

    /**
     * 获取数据源lookupkey
     *
     * @param joinPoint
     * @return
     */
    public String getDataSourceName(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        if (method != null) {
            DataSource dataSource = method.getAnnotation(DataSource.class);

            return dataSource.name();
        } else {
            return null;
        }
    }
}
